於Arduino端接收MQTT資料字串
完成上一個步驟之後,接下來要對 Serial 1進行測試,確保資料在傳送的過程中不會因為電路的誤差而「糟精」(台語:偏差)的疑慮,這種時候,阿海都會直接打開 Arduino IDE 中的範例 「MultiSrerialMEGA」,這個好用的工具範例,修改兩端到要使用的 Buadrate,隨即測試接收資料看看。
圖1:Arduino IDE 中 MultiserialMEGA
圖2:透過 Serial Console確認資料無誤
當確認傳來的資料是相同的之後,就開始著手撰寫通訊程式,Arduino中,剛好能夠利用String 物件輕鬆的操作字串,而MQTT訊息串並不是太大,於是就將所有的資料流存,放到字串裡面。
得到字串之後,就來設計解析字串程式,這邊要取得的有「日期」、「時間」、「溫度」、「溼度」、「PM2.5」、「PM10」這六項資料。其中前兩項並不是數字,所以撰寫一段額外的程序,來分別放置在字串變數,和浮點數陣列之中。而解析時只要找到tag的前置名稱加上「=」號的開頭位置,以及結尾的「|」符號,就能夠取出這段資料。
首先宣告想要截取的特徵前導字元:
#include <avr/pgmspace.h>
const char data_datep[] PROGMEM = "date";
const char data_timep[] PROGMEM = "time";
const char interestValue_1[] PROGMEM = "s_d0";
const char interestValue_2[] PROGMEM = "s_t0";
const char interestValue_3[] PROGMEM = "s_h0";
const char interestValue_4[] PROGMEM = "s_d1";
const char* const interestValue[] PROGMEM = {data_datep, data_timep , interestValue_1, interestValue_2, interestValue_3, interestValue_4, };
然後尋找特徵碼的開頭,並使用 String.indexOf 定位,將所需要的部分轉換成數值,存放在浮點數陣列之中。
float sensorValue[4];
char buffer[8];
boolean onMessage(){
Serial.println("OnMessage");
for(int i=0;i<=data_num-1;i++){
strcpy_P(buffer, (char*)pgm_read_word(&(interestValue[i])));
byte startpos=msg.indexOf(buffer);
String temp =msg.substring(msg.indexOf(assigner,startpos)+1,msg.indexOf(seperator,startpos)); //From tagname after'=' to seperator'|'
if(temp==""){
return 0; //if failed to match tags....
}
if(i==0){
data_date = temp;
} else if(i==1){
data_time = temp;
} else {
sensorValue[i-2]=temp.toFloat();
}
Serial.println(temp);
}
return 1; // I count 2440 message/second with static process , so maybe perfomence is about 100~1000 message/s.
}
將這些資料印在Serial上,確認解析字串成功之後,就要準備來顯示在 128 x 64 的繪圖型 OLED 上了。
圖3:於Serial觀察解析字串的結果